package cn.boodqian.airreport;

import java.text.DateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gson.*;

import cn.boodqian.util.*;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.Filter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast;

public class LocationSelectActivity extends Activity implements TextWatcher, OnItemClickListener {
	private GAERequest mAirdataRequest = new GAERequest(GlobalData.gGAEProject);
	private Gson mGson = new GsonBuilder().setDateFormat(DateFormat.FULL, DateFormat.FULL).create();
	private Handler handler = new Handler();
	private ListView mListLocation;
	private Drawable searchIcon;
	private EditText mEditSearch; 
	private MySimpleAdapter mSearchAdapter = null;
	private GlobalData mGlobalData = null;
	private Thread mLocationCodeThd = null;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.location_select);
		
		mGlobalData = GlobalData.getInstance();
		
		mListLocation = (ListView) findViewById(R.id.list_location);
		mEditSearch = (EditText) findViewById(R.id.edit_search);
		
		mEditSearch.addTextChangedListener(this);
		mListLocation.setOnItemClickListener(this);

		searchIcon = getResources().getDrawable(android.R.drawable.ic_menu_search);
		mEditSearch.post(new Runnable() {
			public void run() {
				android.text.TextPaint paint = mEditSearch.getPaint();
				android.widget.RelativeLayout.LayoutParams lp = (android.widget.RelativeLayout.LayoutParams)mEditSearch.getLayoutParams();
				Log.i(String.format("%f,%d,%d,%d", -paint.ascent() + paint.descent(), mEditSearch.getHeight(),  lp.bottomMargin, lp.topMargin));
				int size = mEditSearch.getHeight()-lp.bottomMargin-lp.topMargin;
				searchIcon.setBounds(0, 0, size, size);
				mEditSearch.setCompoundDrawables(null, null, searchIcon, null);
			}
		});
	}

	private void updateLocationListUI()
	{
		if(mGlobalData.gLocationList == null) {
			Log.w("mGlobalData.gLocationList is null");
			return;
		}
		
		mSearchAdapter = new MySimpleAdapter(this, mGlobalData.gLocationList,
				R.layout.location_select_item, new String[]{"city", "name", "address", "tip"},
				new int[]{R.id.text_city, R.id.text_name, R.id.text_address, R.id.text_tip});
		mListLocation.setAdapter(mSearchAdapter);
	}
	
	private void updateLocationList(final Runnable run)
	{
		// Location info already there
		Log.i("" + mGlobalData.gLocationNeedUpdate);
		if ( mGlobalData.gLocationList != null && mGlobalData.gLocationList.size() > 0 &&
				!mGlobalData.gLocationNeedUpdate ) {
			run.run();
			return;
		}
		
		final ProgressDialog dlg = ProgressDialog.show(this,
				getString(R.string.refresh_wait),
				getString(R.string.refresh_location), true);

		// Use thread to prevent any possible UI freezes
		Thread thd = new Thread() {
			@Override
			public void run() {
				mGlobalData.gLocationList = null;
				JsonParser parser = new JsonParser();
				try {
					String str = mAirdataRequest.doGet("/location/list?lang=" + getString(R.string.lang));
					JsonArray array = parser.parse(str).getAsJsonArray();
					mGlobalData.gLocationList = new ArrayList<HashMap<String,String>>();
					for(JsonElement e:array) {
						HashMap map = mGson.fromJson(e, HashMap.class);
						mGlobalData.gLocationList.add(map);
					}
				} catch (Exception e) {
					mGlobalData.gLocationList = null;
					e.printStackTrace();
				}
				handler.post(new Runnable() {
					@Override
					public void run() {
						if (mGlobalData.gLocationList == null) {
							Toast.makeText(
									dlg.getContext(),
									getString(R.string.refresh_error) + "\n"
											+ mAirdataRequest.getLastError(),
									Toast.LENGTH_LONG).show();
						} else {
							Toast.makeText(dlg.getContext(),
									getString(R.string.refresh_done),
									Toast.LENGTH_LONG).show();
						}
						
						mGlobalData.gLocationNeedUpdate = false;
						dlg.dismiss();

						if (run != null)
							run.run();
					}
				});
			}
		};
		thd.start();
	}

	@Override
	public void afterTextChanged(Editable s) {
		mSearchAdapter.getFilter().filter(s.toString());
	}

	@Override
	public void beforeTextChanged(CharSequence s, int start, int count,
			int after) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onTextChanged(CharSequence s, int start, int before, int count) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
		HashMap<String,String> map = (HashMap<String, String>)parent.getItemAtPosition(position);
		switch(parent.getId()) {
		case R.id.list_location:
			Intent intent = new Intent();
			intent.putExtra("id", map.get("id"));
			setResult(0, intent);
			finish();
			break;
		default:
			assert(false);	
		}
	}
	
	@Override
	public void onStart() {
		super.onStart();
		
		// Location version check
		if( mLocationCodeThd==null && !mGlobalData.gLocationNeedUpdate ) {
			mLocationCodeThd = new Thread() {
				@Override
				public void run() {
					try {
						String str = mAirdataRequest.doGet("/location/code");
						int newLocationCode = mGson.fromJson(str, int.class);
						if( mGlobalData.gLastLocationCode != newLocationCode ) {
							Log.i("location need update: old/new = " +
									mGlobalData.gLastLocationCode + "/" +
									newLocationCode );
							mGlobalData.gLocationNeedUpdate = true;
							mGlobalData.gLastLocationCode = newLocationCode;
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
					mLocationCodeThd = null;
				}
			};
			mLocationCodeThd.start();
		}
		
		// Update location list if necessary
		updateLocationList(new Runnable() {
			@Override
			public void run() {
				updateLocationListUI();
			}
		});
	}
}
